import { useCallback, useState } from 'react';
import { useDispatch } from 'react-redux';
import { updateTrackItemAndSyncMaterial } from '@/store/tracksSlice';
import { setShouldTriggerClickAfterAudioDrag, setShouldTriggerClickAfterTextDrag, setShouldTriggerClickAfterStickerDrag, setShouldTriggerClickAfterVideoDrag } from '@/store/editingSlice';

/**
 * 拖拽工具函数集合
 */
namespace DragUtils {
    /**
     * 逻辑0: 视频小盒子专用 - 禁用拖拽功能
     * 由于视频小盒子不能左右拖拽，提供一个空实现
     * @returns 空的拖拽处理对象
     */
    export const useVideoNoDrag = () => {
        return { isDragging: false, handleMouseDown: () => {} };
    };

    /**
     * 逻辑1: 左右拖拽功能 - 适用于除视频外的所有小盒子
     * @param trackId 轨道ID
     * @param itemId 项目ID
     * @param start 初始位置
     * @param pixelsPerSecond 每秒像素数
     * @returns 拖拽处理函数
     */
    export const useHorizontalDrag = (trackId: string, itemId: string, start: number, pixelsPerSecond: number) => {
        const dispatch = useDispatch();
        const [isDragging, setIsDragging] = useState(false);

        const handleMouseDown = useCallback(
            (e: React.MouseEvent) => {
                e.stopPropagation();
                e.preventDefault();
                if (e.button !== 0) return;

                setIsDragging(true);
                const startX = e.clientX;
                const startLeft = start;

                const handleMouseMove = (moveEvent: MouseEvent) => {
                    const deltaX = moveEvent.clientX - startX;
                    const deltaMs = deltaX / pixelsPerSecond;
                    const newStart = Math.max(0, startLeft + deltaMs);

                    dispatch(
                        updateTrackItemAndSyncMaterial({
                            trackId,
                            itemId,
                            updates: { start: newStart },
                        })
                    );
                };

                const handleMouseUp = () => {
                    setIsDragging(false);
                    window.removeEventListener('mousemove', handleMouseMove);
                    window.removeEventListener('mouseup', handleMouseUp);

                    // 根据trackId判断素材类型并设置对应状态
                    if (trackId.includes('audio') || trackId.includes('narration')) {
                        dispatch(setShouldTriggerClickAfterAudioDrag(true));
                    } else if (trackId.includes('text')) {
                        dispatch(setShouldTriggerClickAfterTextDrag(true));
                    } else if (trackId.includes('sticker')) {
                        dispatch(setShouldTriggerClickAfterStickerDrag(true));
                    }
                };

                window.addEventListener('mousemove', handleMouseMove);
                window.addEventListener('mouseup', handleMouseUp);
            },
            [dispatch, trackId, itemId, start, pixelsPerSecond]
        );

        return { isDragging, handleMouseDown };
    };

    /**
     * 逻辑2: 拖拽右侧改变宽度功能 - 所有小盒子都需要
     * @param trackId 轨道ID
     * @param itemId 项目ID
     * @param start 初始位置
     * @param duration 初始持续时间
     * @param pixelsPerSecond 每秒像素数
     * @returns 右侧拖拽处理函数
     */
    export const useRightResize = (trackId: string, itemId: string, start: number, duration: number, pixelsPerSecond: number) => {
        const dispatch = useDispatch();
        const [isResizing, setIsResizing] = useState(false);

        const handleResizeStart = useCallback(
            (e: React.MouseEvent) => {
                e.stopPropagation();
                if (e.button !== 0) return;

                setIsResizing(true);
                const startX = e.clientX;
                const initialDuration = duration;

                const handleMouseMove = (moveEvent: MouseEvent) => {
                    const deltaX = moveEvent.clientX - startX;
                    const deltaMs = deltaX / pixelsPerSecond;
                    const newDuration = Math.max(1, initialDuration + deltaMs); // 设置最小为1ms

                    dispatch(
                        updateTrackItemAndSyncMaterial({
                            trackId,
                            itemId,
                            updates: { duration: newDuration },
                        })
                    );
                };

                const handleMouseUp = () => {
                    setIsResizing(false);
                    window.removeEventListener('mousemove', handleMouseMove);
                    window.removeEventListener('mouseup', handleMouseUp);

                    // 根据trackId判断素材类型并设置对应状态
                    if (trackId.includes('audio') || trackId.includes('narration')) {
                        dispatch(setShouldTriggerClickAfterAudioDrag(true));
                    } else if (trackId.includes('text')) {
                        dispatch(setShouldTriggerClickAfterTextDrag(true));
                    } else if (trackId.includes('sticker')) {
                        dispatch(setShouldTriggerClickAfterStickerDrag(true));
                    }
                };

                window.addEventListener('mousemove', handleMouseMove);
                window.addEventListener('mouseup', handleMouseUp);
            },
            [dispatch, trackId, itemId, duration, pixelsPerSecond]
        );

        return { isResizing, handleRightResize: handleResizeStart };
    };

    /**
     * 增强版逻辑2: 视频小盒子拖拽右侧改变宽度时，后面的小盒子跟随移动
     * @param trackId 轨道ID
     * @param itemId 项目ID
     * @param start 初始位置
     * @param duration 初始持续时间
     * @param pixelsPerSecond 每秒像素数
     * @param items 轨道上的所有项目
     * @returns 右侧拖拽处理函数
     */
    export const useVideoRightResizeWithFollow = (trackId: string, itemId: string, start: number, duration: number, pixelsPerSecond: number, items: any[]) => {
        const dispatch = useDispatch();
        const [isResizing, setIsResizing] = useState(false);

        const handleResizeStart = useCallback(
            (e: React.MouseEvent) => {
                e.stopPropagation();
                if (e.button !== 0) return;

                setIsResizing(true);
                const startX = e.clientX;
                const initialDuration = duration;
                const initialEnd = start + duration;

                const handleMouseMove = (moveEvent: MouseEvent) => {
                    const deltaX = moveEvent.clientX - startX;
                    const deltaMs = deltaX / pixelsPerSecond;
                    const newDuration = Math.max(1, initialDuration + deltaMs);
                    const newEnd = start + newDuration;
                    const deltaEnd = newEnd - initialEnd;

                    // 更新当前视频小盒子的持续时间
                    dispatch(
                        updateTrackItemAndSyncMaterial({
                            trackId,
                            itemId,
                            updates: { duration: newDuration },
                        })
                    );

                    // 移动后面的所有小盒子
                    // 找出当前轨道上在当前小盒子后面的所有项目
                    const itemsToMove = items.filter((item) => item.id !== itemId && item.start >= initialEnd).sort((a, b) => a.start - b.start);

                    // 移动这些项目
                    itemsToMove.forEach((item) => {
                        dispatch(
                            updateTrackItemAndSyncMaterial({
                                trackId,
                                itemId: item.id,
                                updates: { start: item.start + deltaEnd },
                            })
                        );
                    });
                };

                const handleMouseUp = () => {
                    setIsResizing(false);
                    window.removeEventListener('mousemove', handleMouseMove);
                    window.removeEventListener('mouseup', handleMouseUp);

                    // 视频轨道拖拽结束后设置状态
                    dispatch(setShouldTriggerClickAfterVideoDrag(true));
                };

                window.addEventListener('mousemove', handleMouseMove);
                window.addEventListener('mouseup', handleMouseUp);
            },
            [dispatch, trackId, itemId, start, duration, pixelsPerSecond, items]
        );

        return { isResizing, handleRightResize: handleResizeStart };
    };

    /**
     * 逻辑3: 防止重叠功能 - 所有小盒子都需要
     * 注: 此函数需要在拖拽结束后调用，检查并调整可能的重叠
     * @param trackId 轨道ID
     * @param itemId 项目ID
     * @param start 新项目开始时间
     * @param duration 新项目持续时间
     * @param items 轨道上的所有项目
     * @returns 处理后的开始时间
     */
    export const preventOverlap = (trackId: string, itemId: string, start: number, duration: number, items: any[]): number => {
        // 过滤出当前轨道上的其他项目
        const otherItems = items.filter((item) => item.id !== itemId);

        // 检查是否有重叠
        for (const item of otherItems) {
            const itemEnd = item.start + item.duration;
            const newItemEnd = start + duration;

            // 如果有重叠，调整开始时间
            if (start < itemEnd && newItemEnd > item.start) {
                return Math.max(start, itemEnd);
            }
        }

        return start;
    };

    /**
     * 逻辑4: 视频小盒子拖拽改变长度时，后面的小盒子跟随移动
     * @param trackId 轨道ID
     * @param itemId 项目ID
     * @param start 初始位置
     * @param duration 初始持续时间
     * @param pixelsPerSecond 每秒像素数
     * @param items 轨道上的所有项目
     * @returns 拖拽处理函数
     */
    export const useVideoResizeWithFollow = (trackId: string, itemId: string, start: number, duration: number, pixelsPerSecond: number, items: any[]) => {
        const dispatch = useDispatch();
        const [isResizing, setIsResizing] = useState(false);

        const handleResizeStart = useCallback(
            (e: React.MouseEvent) => {
                e.stopPropagation();
                if (e.button !== 0) return;

                setIsResizing(true);
                const startX = e.clientX;
                const initialDuration = duration;
                const initialEnd = start + duration;

                const handleMouseMove = (moveEvent: MouseEvent) => {
                    const deltaX = moveEvent.clientX - startX;
                    const deltaMs = deltaX / pixelsPerSecond;
                    const newDuration = Math.max(1, initialDuration + deltaMs);
                    const newEnd = start + newDuration;
                    const deltaEnd = newEnd - initialEnd;

                    // 更新当前视频小盒子的持续时间
                    dispatch(
                        updateTrackItemAndSyncMaterial({
                            trackId,
                            itemId,
                            updates: { duration: newDuration },
                        })
                    );

                    // 如果结束时间增加了，移动后面的所有小盒子
                    if (deltaEnd > 0) {
                        // 找出当前轨道上在当前小盒子后面的所有项目
                        const itemsToMove = items.filter((item) => item.id !== itemId && item.start >= initialEnd).sort((a, b) => a.start - b.start);

                        // 移动这些项目
                        itemsToMove.forEach((item) => {
                            dispatch(
                                updateTrackItemAndSyncMaterial({
                                    trackId,
                                    itemId: item.id,
                                    updates: { start: item.start + deltaEnd },
                                })
                            );
                        });
                    }
                };

                const handleMouseUp = () => {
                    setIsResizing(false);
                    window.removeEventListener('mousemove', handleMouseMove);
                    window.removeEventListener('mouseup', handleMouseUp);

                    // 视频轨道拖拽结束后设置状态
                    dispatch(setShouldTriggerClickAfterVideoDrag(true));
                };

                window.addEventListener('mousemove', handleMouseMove);
                window.addEventListener('mouseup', handleMouseUp);
            },
            [dispatch, trackId, itemId, start, duration, pixelsPerSecond, items]
        );

        return { isResizing, handleVideoResize: handleResizeStart };
    };
}

export default DragUtils;
